use crate::extractor::TypedHeader;
use crate::header::Token;
use crate::{rediss, ApiError, Auth, ToError};
use axum::extract::FromRequestParts;
use axum::http::request::Parts;
use redis::AsyncCommands;
use serde::de::DeserializeOwned;

/// 获取存储的用户信息
pub struct UserStore<T>(pub T);

impl<S, T> FromRequestParts<S> for UserStore<T>
where
    T: DeserializeOwned,
    S: Send + Sync,
{
    type Rejection = ApiError;

    async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
        let res = TypedHeader::<Token>::from_request_parts(parts, state).await;
        let TypedHeader(Token(token)) =
            res.to_err(|| ApiError::Authorization(Auth::NoToken))?;
        let mut connect = rediss::get().await?;
        let user: rediss::RedisJson<T> = connect
            .get(token)
            .await
            .to_err(|| ApiError::Authorization(Auth::TokenExpire))?;

        Ok(Self(user.0))
    }
}
